import {
  AmbientLight,
  AxesHelper,
  DirectionalLight,
  GridHelper,
  Group,
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
} from "three";
import { GLTFLoader, OrbitControls } from "three/examples/jsm/Addons.js";

export default class Y3DEngine {
  constructor() {
    this.init();
    this.animate();
  }

  init() {
    this.initScene();
    this.initLights();
    this.initHelper();
    this.initCamera();
    this.initRenderer();
    this.initControls();
    this.initEvents();
  }

  initEvents() {
    window.addEventListener("resize", this.onWindowResize);
  }

  onWindowResize = () => {
    this.camera.aspect = this.aspect;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(this.width, this.height);
  };

  loadGLTFModel = async (path) => {
    const loader = new GLTFLoader();
    loader.setCrossOrigin("anonymous");
    try {
      const gltf = await loader.loadAsync(path);
      this.scene.add(gltf.scene);
    } catch (error) {
      console.log("Error loading GLTF model:", error);
    }
  };

  initControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.enableDamping = true;
    this.controls.dampingFactor = 0.25;
    this.controls.screenSpacePanning = false;
    // this.controls.maxPolarAngle = Math.PI / 2;
  }

  initLights() {
    this.lights = new Group();
    this.scene.add(this.lights);
    this.lights.add(new AmbientLight(0xffffff, 3));
    const directionalLight = new DirectionalLight(0xffffff, 1);
    directionalLight.position.set(1, 1, 1);
    this.lights.add(directionalLight);
  }

  initHelper() {
    this.helpers = new Group();
    this.scene.add(this.helpers);
    this.helpers.add(new AxesHelper(50));
    this.helpers.add(new GridHelper(100, 10));
  }

  initRenderer() {
    this.renderer = new WebGLRenderer({ antialias: true });
    this.renderer.setSize(this.width, this.height);
    document.body.appendChild(this.renderer.domElement);
  }

  get height() {
    return window.innerHeight;
  }

  get width() {
    return window.innerWidth;
  }

  get aspect() {
    return this.width / this.height;
  }

  initCamera() {
    this.camera = new PerspectiveCamera(75, this.aspect, 0.1, 10000);
    this.camera.position.set(0, 1.5, 3);
    this.camera.lookAt(0, 0, 0);
  }

  initScene() {
    this.scene = new Scene();
  }

  animate = () => {
    requestAnimationFrame(this.animate);
    this.renderer.render(this.scene, this.camera);
  };
}

window.addEventListener("DOMContentLoaded", () => {
  const y3d = new Y3DEngine();
  y3d.loadGLTFModel("./水泥抗压抗折万能试验机.glb");
  window.y3d = y3d;
});
